#include "GstreamerFilter.h"


void *CGstreamerFilter::m_hWndOverlay;

CGstreamerFilter::CGstreamerFilter()
{
}


CGstreamerFilter::~CGstreamerFilter()
{
}


static GstBusSyncReply bus_sync_handler(GstBus * bus, GstMessage * message, gpointer user_data)
{
	// ignore anything but 'prepare-window-handle' element messages
	if (!gst_is_video_overlay_prepare_window_handle_message(message))
		return GST_BUS_PASS;

	if (user_data){
		if (CGstreamerFilter::m_hWndOverlay) {
			GstVideoOverlay *overlay;
			guintptr handle = (guintptr)CGstreamerFilter::m_hWndOverlay;
			overlay = GST_VIDEO_OVERLAY(GST_MESSAGE_SRC(message));
			gst_video_overlay_set_window_handle(overlay, handle);
		}
		else {
			g_warning("Should have obtained video_window_handle by now!");
		}
	}

	gst_message_unref(message);
	return GST_BUS_DROP;
}

int CGstreamerFilter::launch_avlog_pipeline(string & strFileUrl, void * hWndOverlay)
{
	m_hWndOverlay = hWndOverlay;
	GMainLoop *loop;
	GMainContext* cxt = NULL;

	static bool bInited = false;
	if (!bInited){
		gst_init(NULL, NULL);
		bInited = true;
	}
	g_print("CGstAVLog::Play(),new main loop ...\n");

	cxt = g_main_context_new();
	g_main_context_push_thread_default(cxt);
	//loop = g_main_loop_new(NULL, FALSE);
	loop = g_main_loop_new(cxt, FALSE);



	//gst-launch-1.0 -v avimux name=mux ! filesink name=file location=test.avi autovideosrc name=video_src  ! tee name=t ! queue ! videorate ! videoconvert ! x264enc tune=zerolatency ! queue ! mux. autoaudiosrc ! audiorate ! audioconvert ! lamemp3enc target=1 bitrate=64 cbr=true ! queue max-size-time=0 max-size-buffers=0  max-size-bytes=0 ! mux. t. ! queue !  videorate ! videoconvert ! queue ! autovideosink
	GstBus *bus;
	guint bus_watch_id = 0;
	GError *error = NULL;
	//workable  h264+mp3
	//string strLaunch = "avimux name=mux ! filesink name=file location=" + strFileUrl + " autovideosrc name=video_src  ! tee name=t ! queue ! videorate ! videoconvert ! x264enc tune=zerolatency ! queue ! mux. autoaudiosrc ! audiorate ! audioconvert ! lamemp3enc target=1 bitrate=64 cbr=true ! queue max-size-time=0 max-size-buffers=0  max-size-bytes=0 ! mux. t. ! queue !  videorate ! videoconvert ! queue ! autovideosink";
	//string strLaunch = "avimux name=mux ! filesink name=file location=test.avi autovideosrc name=video_src  ! tee name=t ! queue ! videorate ! videoconvert ! x264enc tune=zerolatency ! queue ! mux. autoaudiosrc ! audiorate ! audioconvert ! lamemp3enc target=1 bitrate=64 cbr=true ! queue max-size-time=0 max-size-buffers=0  max-size-bytes=0 ! mux. t. ! queue !  videorate ! videoconvert ! queue ! autovideosink";

	//workable h264+PCM(by default,2channel.1KHz,16bit,little,signal)
	//string strLaunch = "avimux name=mux ! filesink name=file location=" + strFileUrl + " autovideosrc name=video_src  ! tee name=t ! queue ! videorate ! videoconvert ! x264enc tune=zerolatency ! queue ! mux. autoaudiosrc ! audiorate ! audioconvert  ! queue max-size-time=0 max-size-buffers=0  max-size-bytes=0 ! mux. t. ! queue !  videorate ! videoconvert ! queue ! autovideosink";

	string strLaunch = "avimux name=mux ! filesink name=file location=" + strFileUrl + " autovideosrc name=video_src  ! tee name=t ! queue ! videorate ! videoconvert ! x264enc tune=zerolatency ! queue ! mux. autoaudiosrc ! audiorate ! audioconvert ! audio/x-raw, format=S16LE, rate=8000, channels=1 ! queue max-size-time=0 max-size-buffers=0  max-size-bytes=0 ! mux. t. ! queue !  videorate ! videoconvert ! queue ! autovideosink";


	GstElement *pipeline = gst_parse_launch(strLaunch.c_str(), &error);

	if (error) {
		return -1;
	}


	bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
	gst_bus_set_sync_handler(bus, (GstBusSyncHandler)bus_sync_handler, this, NULL);
	gst_object_unref(bus);

	gst_element_set_state(pipeline, GST_STATE_PLAYING);

	m_pipeline = pipeline;
	m_main_loop = loop;
	g_main_loop_run(loop);


	g_main_loop_unref(loop);
	g_main_context_unref(cxt);
	return 0;
}

void CGstreamerFilter::Stop()
{
	if (!m_pipeline){
		return;
	}
	gst_element_set_state(m_pipeline, GST_STATE_NULL);
	g_object_unref(m_pipeline);
	m_pipeline = NULL;
	g_main_loop_quit(m_main_loop);
}

